using System;
using System.Web;
using Headspring.Training.Domain;
using Headspring.Training.Domain.Model;
using Headspring.Training.Domain.Services;
using StructureMap;

namespace Headspring.Training.WebUI.Services.Impl
{
	[Pluggable(Keys.DEFAULT)]
	public class WorkflowCoordinator : IWorkflowCoordinator
	{
		private IWorkOrderRepository _repository;
		private IUserSession _session;
		private readonly INotificationFactory _factory;
		private readonly INotificationSender _sender;
		private readonly IClock _clock;

		public WorkflowCoordinator(IWorkOrderRepository repository, 
			IUserSession session, INotificationFactory factory, INotificationSender sender, IClock clock)
		{
			_repository = repository;
			_session = session;
			_factory = factory;
			_sender = sender;
			_clock = clock;
		}

		public void SaveWorkOrder(WorkOrder workOrder)
		{
			_repository.Save(workOrder);
		}

		public void EditWorkOrder(WorkOrder workOrder)
		{
			HttpResponse response = HttpContext.Current.Response;
			response.Redirect("~/SingleWorkOrder.aspx?mode=edit&wo_number=" + workOrder.Number);
		}

		public void GoToWorkOrderSearch(Employee creator, Employee assignee, WorkOrderStatus status)
		{
			string url = string.Format("~/SearchWorkOrders.aspx?creator={0}&assignee={1}&status={2}",
			                           getNullSafeUserName(creator), getNullSafeUserName(assignee), getNullSafeStatusKey(status));
			HttpResponse response = HttpContext.Current.Response;
			response.Redirect(url);
		}

		public void SendMessage(string message)
		{
			_session.PushUserMessage(new FlashMessage(FlashMessage.MessageType.Message, message));
		}

		public void SendError(string message)
		{
			_session.PushUserMessage(new FlashMessage(FlashMessage.MessageType.Error, message));
		}

		private string getNullSafeStatusKey(WorkOrderStatus status)
		{
			if (status == null)
			{
				return null;
			}

			return status.Key;
		}

		private string getNullSafeUserName(Employee employee)
		{
			if (employee == null)
			{
				return null;
			}

			return employee.UserName;
		}

		public void SendNotification(IStateCommand command, WorkOrder order)
		{
			WorkOrderNotification notification = _factory.CreateNotification(command, order);
			NotificationType type = notification.Recipient.GetNotificationTypeFor(_clock.GetCurrentTime().DayOfWeek);
			if (type != NotificationType.None)
			{
				_sender.Send(notification);
			}
		}
	}
}